# 魔改G6 imageMinimap

# 背景

G6有提供两种缩略图,minimap和imageMinimap。

区别就是minimap是根据graph再用canvas画一次,而imageminimap是将我们自己给的图片显示出来(但是需要自己监听变化并给出图片)。

可想而知,在大量数据的情况下,双倍渲染canvas肯定消耗更大的性能,下面就来魔改下imageMinimap,使其能监听graph变化,自动生成图片并渲染到缩略图上。

# 实现

首先在'@antv/g6/es/plugins/minimap/index' 看minimap的源代码,看是怎么实现监听graph变化的。

发现在init函数中做了监听,回调handleUpdateCanvas做了防抖

MiniMap.prototype.init = function () {
    this.initContainer();
    this.get('graph').on('afterupdateitem', this.handleUpdateCanvas);
    this.get('graph').on('afteritemstatechange', this.handleUpdateCanvas);
    this.get('graph').on('afteradditem', this.handleUpdateCanvas);
    this.get('graph').on('afterremoveitem', this.handleUpdateCanvas);
    this.get('graph').on('afterrender', this.handleUpdateCanvas);
    this.get('graph').on('afterlayout', this.handleUpdateCanvas);
};
function MiniMap() {
  var _this = _super !== null && _super.apply(this, arguments) || this;
  /**
   * 主图更新的监听函数,使用 debounce 减少渲染频率
   * e.g. 拖拽节点只会在松手后的 100ms 后执行 updateCanvas
   * e.g. render 时大量 addItem 也只会执行一次 updateCanvas
   */
  _this.handleUpdateCanvas = debounce(function (event) {
    var self = _this;
    if (self.destroyed) return;
    self.updateCanvas();
  }, 100, false);
  return _this;
}

下面就来实现我们自己的逻辑,先引入源代码,再使用新函数去继承。

主要改动就是监听到变化后调用api获取canvas图片,并调用imageMinimap的更新图片方法即可。

import ImageMinimap from '@antv/g6/es/plugins/imageMinimap/index';
import extendMinimap from './extendMinimap';
const MagicImageMiniMap = extendMinimap(ImageMinimap);
import { debounce } from '@antv/util';

export default (ImageMinimap) => {
  function MagicImageMiniMap(cfg) {
    this.cfg = cfg;
    ImageMinimap.call(this);
    const _this = this;

    this.handleUpdateCanvas = debounce(function (event) {
      if (_this.destroyed) return;
      _this.generateFullImage();
    }, 300, false);
  }
  MagicImageMiniMap.prototype = Object.create(ImageMinimap.prototype);

  MagicImageMiniMap.prototype.constructor = MagicImageMiniMap;

  MagicImageMiniMap.prototype.init = function() {
    ImageMinimap.prototype.init.call(this);
    this.get('graph').on('afterupdateitem', this.handleUpdateCanvas);
    this.get('graph').on('afteritemstatechange', this.handleUpdateCanvas);
    this.get('graph').on('afteradditem', this.handleUpdateCanvas);
    this.get('graph').on('afterremoveitem', this.handleUpdateCanvas);
    this.get('graph').on('afterrender', this.handleUpdateCanvas);
    this.get('graph').on('afterlayout', this.handleUpdateCanvas);
  };

  MagicImageMiniMap.prototype.getDefaultCfgs = function () {
    const cfg = ImageMinimap.prototype.getDefaultCfgs.call(this);
    return Object.assign(cfg, this.cfg);
  };

  MagicImageMiniMap.prototype.generateFullImage = function () {
    const graph = this.get('graph');
    graph.toFullDataURL((res) => {
      this.updateGraphImg(res);
    });
  };
  return MagicImageMiniMap;
};